#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

static bool is_init = false;
static int cols;

static char *get_progress_format(){
    static char *progress_format = NULL;

    if(is_init && progress_format){
        return progress_format;
    }

    progress_format = (char *)malloc(20);
    memset(progress_format,0,20);

    struct winsize size;
    ioctl(STDIN_FILENO, TIOCGWINSZ, &size);
    cols = size.ws_col;

    // [%-97s]%d%%\r
    
    const char *progress = "[]100%";
    cols = cols - strlen(progress);

    char cols_str[10] = {0};
    sprintf(cols_str,"%d",cols);

    strcat(progress_format,"[%-");
    strcat(progress_format,cols_str);
    strcat(progress_format,"s]%d%%\r");

    is_init = true;

    return progress_format;
}

void download_progress(unsigned long download_size, unsigned long total_size) {
    char *progress_format = get_progress_format();

    char progress_bar[cols];
    memset(progress_bar,0,cols);

    long download_cols = (download_size * cols) / total_size;

    for(long i=1;i<=download_cols;i++) {
        strcat(progress_bar,"=");
    }

    printf(progress_format,progress_bar,(download_size*100)/total_size);
    fflush(stdout);

    if(download_size >= total_size){
        free(progress_format);
        printf("\n");
    }
}

int main()
{

    for(int i=1;i<=500;i++){
        usleep(10000);
        download_progress(i,500);
    }

    return 0;
}

